/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "stdafx.h"

LayoutPool *layoutPool = NULL;

LayoutPool::LayoutPool()
{
}

LayoutPool::~LayoutPool()
{
	for(unsigned ii=0; ii<elements.size(); ii++)
		delete elements[ii];
	elements.clear();
}

void LayoutPool::parseElementList(const string &elements, vector<LayoutElement*> *elementList)
{
	char *tokenizedString = _strdup(elements.c_str());
	elementList->clear();
	
	vector<string> tokens;
	const char *delim = " ;\t\'\"\n\r";
	const char *prefix = strtok(tokenizedString, delim);
	do {
		if(prefix && *prefix) {
			tokens.push_back(prefix);
		}
	} while((prefix = strtok(NULL, delim)));
	
	for(unsigned ii=0; ii<tokens.size(); ii++)
	{
		string prefix = tokens[ii];
		LayoutElement *element = getElement(prefix);
		if(element)
			elementList->push_back(element);
	}
	
	free(tokenizedString);
}

LayoutElement *LayoutPool::getElement(string prefix)
{
	if(constructingElements.find(prefix) != constructingElements.end())
	{
		string errMsg = retprintf("Layout hierarchy is recursive with element %s.", prefix.c_str());
		fatal(errMsg.c_str());
	}
	
	if(cachedElements.find(prefix) == cachedElements.end())
	{
		constructingElements.insert(prefix);
			LayoutElement *element = createElement(prefix);
			cachedElements[prefix] = element;
		constructingElements.erase(prefix);
		
		if(element)
			elements.push_back(element);
	}
	
	return cachedElements[prefix];
}

LayoutElement *LayoutPool::getSpacerElement(int size, bool optional, bool expanding)
{
	LayoutElement *element = new SpacerElement(size, optional, expanding);
	elements.push_back(element);
	return element;
}

LayoutElement *LayoutPool::createElement(string prefix)
{
	if(prefix=="")
		return NULL;
	
	if(prefix=="null")
		return new NullElement();
	
	string type = getConfigString("Type", NULL, prefix.c_str());
	if(type == "")
		return NULL;

	if(!_stricmp(type.c_str(), "group"))
		return new GroupElement(prefix);
	else if(!_stricmp(type.c_str(), "flow"))
		return new LinearFlow(prefix);
	else if(!_stricmp(type.c_str(), "label"))
		return new TextLabelElement(prefix);
	else if(!_stricmp(type.c_str(), "module")) {
		try {
			return new ChildModuleElement(prefix);
		} catch(ModuleLoadException) {
			return NULL;
		}
	} else if(!_stricmp(type.c_str(), "texture"))
		return new TextureElement(prefix);
	else if(!_stricmp(type.c_str(), "minimap"))
		return new MinimapElement(prefix);
	else if(!_stricmp(type.c_str(), "icon"))
		return new TaskIconElement(prefix);
	else if(!_stricmp(type.c_str(), "branch"))
		return new BranchElement(prefix);
	else if(!_stricmp(type.c_str(), "null"))
		return new NullElement();
	else if(!_stricmp(type.c_str(), "start"))
		return new StartButtonElement(prefix);
	else if(!_stricmp(type.c_str(), "snapshot"))
		return new SnapshotElement(prefix);
	else {
		string err = string("Invalid value \"")+type+"\" for element \""+prefix+"Type\".";
		warn(err.c_str());
		return NULL;
	}
}
